﻿package nl.sanity.net 
{
	import flash.events.ErrorEvent;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.ProgressEvent;
	import flash.net.FileReference;
	import flash.net.FileReferenceList;
	import flash.net.FileFilter;
	import flash.net.URLRequest;
	
	import nl.sanity.debug.LogConsole;
	
	/**
	 * FileUploader
	 * File upload manager
	  * 
	 * @langversion ActionScript 3
	 *
	 * @author A. Gosman
	 * @since  28/03/2009
	 */
	public class FileUploader extends EventDispatcher
	{
		public static const IMAGE_FILTER	: FileFilter	= new FileFilter( "Images", "*.jpg; *.jpeg; *.gif; *.png" );
		public static const VIDEO_FILTER	: FileFilter	= new FileFilter( "Video", "*.mpg; *.mpeg; *.flv; *.mov; *.asf; *.wmv; *.divx; *.avi; *.qt; *.mp4; *.3gp" );
		public static const TEXT_FILTER		: FileFilter	= new FileFilter( "Text Files", "*.txt; *.rtf" );
		public static const NO_FILTER		: FileFilter	= new FileFilter( "All Formats (*.*)", "*.*" );
		
		protected var _url 					: String;
		protected var _filters 				: Array;
		protected var _allowMultiple		: Boolean;
		protected var _uploadAfterSelect	: Boolean;
		
		protected var _fileReference		: FileReference;
		protected var _fileReferenceList	: FileReferenceList;
		
		// --- CONSTRUCTOR ----------------------------------------

		public function FileUploader( url:String = "", filters:Array = null, allowMultiple:Boolean = false, uploadAfterSelect:Boolean = false ) 
		{
			_url				= url;
			_filters			= filters || [ FileUploader.NO_FILTER ];
			_allowMultiple		= allowMultiple;
			_uploadAfterSelect	= uploadAfterSelect;
			
			_allowMultiple ? setupFileReferenceList() : setupFileReference();
		}
		
		// --- PUBLIC FUNCTIONS ----------------------------------------
		
		public function browse():Boolean
		{
			LogConsole.info( "FileUploader.browse | allowMultiple: " + _allowMultiple );
			
			if ( _allowMultiple )
			{
				return _fileReferenceList.browse( _filters );
			}
			else
			{
				return _fileReference.browse( _filters );
			}
		}
		
		public function upload( file:FileReference, urlRequest:URLRequest = null ):void
		{
			LogConsole.info ( "FileUploader.upload" );
			
			urlRequest 	= urlRequest || new URLRequest( _url );
			
			file.addEventListener( Event.COMPLETE, onFileUploadComplete, false, 0, true );
			file.addEventListener( ProgressEvent.PROGRESS, onFileUploadProgress, false, 0, true );
			
			try
			{
				LogConsole.info( "File to upload: " + file.name + " (" + file.size + " bytes)" );
				file.upload( urlRequest );
			}
			catch( error:Error )
			{
				LogConsole.warn( "Unable to upload files." );
				
				dispatchEvent( new ErrorEvent( ErrorEvent.ERROR ) );
			}
		}
		
		// --- PROTECTED FUNCTIONS ----------------------------------------

		protected function onFileUploadProgress( event:ProgressEvent ):void 
		{
			dispatchEvent( event );
		}
		
		protected function setupFileReference():void
		{
			//LogConsole.info ( "FileUploader.setupFileReference" );
			_fileReference			= new FileReference();
			_fileReference.addEventListener( Event.SELECT, onFileSelected, false, 0, true );
			
		}
		
		protected function setupFileReferenceList():void
		{
			//LogConsole.info ( "FileUploader.setupFileReferenceList" );
			_fileReferenceList 		= new FileReferenceList();
			_fileReferenceList.addEventListener( Event.SELECT, onFileListSelected, false, 0, true ) ;
		}
		
		protected function onFileSelected( event:Event ):void
		{
			LogConsole.info ( "FileUploader.onFileSelected" );
			
			var file:FileReference		= event.target as FileReference;
			
			dispatchEvent( new Event( Event.SELECT ) );
			
			if ( _uploadAfterSelect )
			{
				upload( file );
			}
		}
		
		protected function onFileListSelected( event:Event ):void
		{
			LogConsole.info ( "FileUploader.onFileListSelected" );
			
			dispatchEvent( new Event( Event.SELECT ) );
			
			if ( _uploadAfterSelect )
			{
				var files:FileReferenceList = FileReferenceList( event.target );
				var selectedFiles:Array 	= files.fileList;
				
				var urlRequest:URLRequest 	= new URLRequest( _url );
				var file:FileReference;
				
				LogConsole.info( "\t no. selected files: " + selectedFiles.length );
				
				for ( var i:uint = 0; i < selectedFiles.length; i++ )
				{
					file 		= FileReference( selectedFiles[ i ] );
					
					upload( file, urlRequest );
				}
			}
		}
		
		protected function onFileUploadComplete( event:Event ):void
		{
			LogConsole.info( "onFileUploadComplete" );
			
			dispatchEvent( new Event( Event.COMPLETE ) );
		}
		
		// --- GETTERS/SETTERS ----------------------------------------
		
		public function get fileReference():FileReference 
		{ 
			return _fileReference; 
		}
		
		public function get fileReferenceList():FileReferenceList 
		{ 
			return _fileReferenceList; 
		}
		
	}
}